import { _decorator, Animation, BoxCollider, Collider, Component, Material, Node, Quat, tween, Vec3 } from 'cc';
import { Ele } from './Ele';
import SoundManager from './SoundManager';
const { ccclass, property } = _decorator;

@ccclass('ZhuZICtr')
export class ZhuZICtr extends Component {
    @property(Node)
    private zhuzi:Node=null;
   
    private mEles=[];
    private mSelect:boolean=false;
    private unlockNum=0;
    private mLen:number=0;
    private mZhuZiRad:number=16.65;
    private mZhuZiHei:number=0.2663;
    private mEleStartY:number=0.2;
   protected onLoad(): void {
       
   }

   public canFly(ctr:ZhuZICtr){
          if(this.mEles.length==0 && this.unlockNum>0)return true;
          if(!this.isFull() && this.mEles[this.mEles.length-1].getComponent(Ele).isSame(ctr.eles[ctr.eles.length-1]))return true;
          return false;
   }

   private mFlyStartPosY:number=10000;
   public addFlyEles(eles,func:Function){
     let tlen=eles.length;
     let tindex=0;
     for(let i=0;i<tlen;i++){
          this.flyOne(eles[i],()=>{
               tindex++;
               if(tindex==tlen){
                    this.mFlyStartPosY=10000;
                    if(func)func();
               }
          },i*0.05,this.mEles.length+i);
     }
   }
   private flyOne(ele:Node,func:Function,dely:number,posIndex:number){
          let twPos=ele.worldPosition;
          let tlpos=new Vec3();
          this.node.inverseTransformPoint(tlpos,twPos);
          ele.parent=this.node;
          ele.setPosition(tlpos);
          if(this.mFlyStartPosY==10000)this.mFlyStartPosY=tlpos.y;
          let tlfinalMaxPosY=this.getMaxPosY();
          let tlFinalPos=this.getLastPos(posIndex);
          let tposY1 = this.mFlyStartPosY+0.1;
          if(tlfinalMaxPosY-this.mFlyStartPosY>0.5)tposY1=tlfinalMaxPosY+0.1;
          let tposY2 = tposY1+2;

          let tlpos1=new Vec3(tlpos.x,tposY1,tlpos.z);
          let tdist1 = Math.abs(tposY1-tlpos.y);

          let tposX = tlpos.x+(tlFinalPos.x-tlpos.x)/2;
          let tposZ = tlpos.z+(tlFinalPos.z-tlpos.z)/2;
          let tlpos2=new Vec3(tposX,tposY2,tposZ);
          let tdist2 = Vec3.distance(tlpos1,tlpos2);

          let tlpos3 = new Vec3(tlFinalPos.x,tposY1,tlFinalPos.z);
          let tdist3 = Vec3.distance(tlpos2,tlpos3);

          let tdist4 = Vec3.distance(tlpos3,tlFinalPos);

          let tslef=this;
          let tsp:number=0.1;
          tween(ele).delay(dely).to(tdist1*tsp,{position:tlpos1}).to(tdist2*tsp,{position:tlpos2}).to(tdist3*tsp,{position:tlpos3}).call(()=>{
               SoundManager.ins.playOneShot("NutTurn");
          }).to(tdist4*tsp,{position:tlFinalPos}).call(()=>{
               tslef.mEles.push(ele);
               SoundManager.ins.playOneShot("down");
               ele.setRotation(new Quat());
               if(func)func()}
          ).start();
   }
   public addEle(ele:Node){
        this.mEles.push(ele);
        this.node.addChild(ele);
        this.freshElePos();
   }

   private mStartRot:Quat=new Quat();
   private mStartScale:Vec3=new Vec3(1,1,1);
   public addEles(eles){
     let tstarty = this.getMaxPosY();
     let ele:Node;
     for(let i=0;i<eles.length;i++){
          ele = eles[i];
          ele.setRotation(this.mStartRot);
          this.mEles.push(ele);
          ele.setPosition(0,tstarty+0.2,0);
          ele.setScale(0,0,0);
          this.node.addChild(ele);
          tween(ele).delay(i*0.1).call(()=>{SoundManager.ins.playOneShot("NutTurn");}).to(0.2,{scale:this.mStartScale}).to(0.2*(eles.length-i),{position:new Vec3(0,this.mEleStartY+i*this.mZhuZiHei,0)}).start();
     }
   }

   public removeAllEles(){
          let teles=[];
          let tele;
          for(let i=0;i<this.mEles.length;i++){
               tele=this.mEles[i];
               tele.removeFromParent();
               teles.push(tele);
          }
          this.mEles=[];
          return teles;
   }

   public setSelect(value:boolean){
        this.mSelect=value;
        if(!this.mEles.length)this.mSelect=false;
        this.freshElePos();
   }

   public getIsSelect(){
          return this.mSelect && this.mEles.length;
   }

   public getSelectFlyNodes(max:number,force:boolean=false){
        let tarr=[];
        let tlen  = this.mEles.length;
        let tmin = tlen-max;
        if(tmin<0)tmin=0;
        let tnotlimit = this.mSelect;
        if(force)tnotlimit=true;
        if(tnotlimit && tlen>0){
            let tfristnode;
            for(let i=tlen-1;i>=tmin;i--){
               if(!tfristnode){
                    tfristnode=this.mEles.splice(i,1)[0];
                    tarr.push(tfristnode);
               }else{
                    if(tfristnode.getComponent(Ele).isSame(this.mEles[i]))tarr.push(this.mEles.splice(i,1)[0]);
                    else break;
               }
            }
        }
        return tarr;
   }

   public getEmptyPosNum(){
          return this.unlockNum-this.mEles.length;
   }

   public clearEles(){
        let teles=this.mEles.slice();
        this.mEles=[];
        return teles;
   }

   public setLen(len:number,allUnlock:boolean=true){
        this.mLen=len;
        if(allUnlock)this.unlockNum=len;
        else this.unlockNum=0;
        this.freshZhuZiBoy();
   }

   public unlockOne(){
        if(this.unlockNum>=this.mLen)return false;
        this.unlockNum++;
        this.freshZhuZiBoy();
        return true;
   }

   public unlockAll(){
        if(this.unlockNum>=this.mLen)return false;
        this.unlockNum = this.mLen;
        this.freshZhuZiBoy();
        return true;
   }

   public isUnlockAll(){
          return this.unlockNum==this.mLen;
   }

   public isComplete(inclueEmpty:boolean=true){
     if(this.mEles.length==0 && inclueEmpty)return true;
     if(this.mEles.length==this.mLen){
          let tele = this.mEles[0];
          for(let i=1;i<this.mEles.length;i++){
               if(!tele.getComponent(Ele).isSame(this.mEles[i]))return false;
          }
          return true;
     }
     return false;
   }

   public rest(){
        this.mLen=0;
        this.mSelect=false;
        this.unlockNum=0;
   }

   public setEleColors(c){
        for(let i=0;i<this.mEles.length;i++){
          this.mEles[i].getComponent(Ele).setEleColor(c[i]);
        }
   }

   public changeSkin(skin,id){
     for(let i=this.mEles.length-1;i>=0;i--){
          if(!this.mEles[i].getComponent(Ele).setSkinTextureInSameId(skin,id))break;
     }
   }

   private freshZhuZiBoy(){
          let tzH =this.mZhuZiHei*100;
        let th = (tzH*this.unlockNum)/2;
        if(th<=10)th=10;
        th += 10;
        this.zhuzi.setScale(this.mZhuZiRad,this.mZhuZiRad,th);
        
        this.zhuzi.setPosition(0,th*0.008,0);
        //console.log("freshZhuZiBoy",th,this.zhuzi);
        this.freshBoxColliderLen();
     }
     
     private mSize:Vec3=new Vec3(1,1,1);
     public freshBoxColliderLen(){
        let tboxc:BoxCollider = this.node.getComponent(BoxCollider);
        let th2 = (this.mZhuZiHei*this.unlockNum);
       let thh = th2;
       this.mSize.y=thh+0.1;
       tboxc.center.y=thh/2-0.1;
       tboxc.size=this.mSize;
      
     //   this.scheduleOnce(()=>{tboxc.size.y += 0.001},2);
   }

   private freshElePos(){
          let ty;
          let tisLast;
        for(let i=0;i<this.mEles.length;i++){
          tisLast = i==this.mEles.length-1;
          if(this.mSelect && tisLast)ty = this.getMaxPosY();
          else ty = this.mEleStartY+i*this.mZhuZiHei;
          this.mEles[i].getComponent(Ele).updatePos(0,ty,0,tisLast,0.05);
        }
   }

   public getChangeIdInfo(){
     let tdata={num:0,id:0};
     let tid;
     for(let i=this.mEles.length-1;i>=0;i--){
          tid = this.mEles[i].getComponent(Ele).getChangeId();
          if(tid>0){
               tdata.num++;
               tdata.id=tid;
          }
          break;
     }
     return tdata;
   }

   private getLastPos(posIndex:number){
          let tVec3=new Vec3(0,this.mEleStartY+posIndex*this.mZhuZiHei,0);
          return tVec3;

   }

   private getMaxPosY(){
     return this.mEleStartY+this.unlockNum*this.mZhuZiHei+0.2
   }

   public get eles(){
     return this.mEles;
   }

   private mRotInfo:Quat=new Quat(0,.5,0);
   protected update(dt: number): void {
        if(this.mSelect){
          //this.mRotInfo.z+=0.01;
          //if(this.mRotInfo.z>=0.1)this.mRotInfo.z=0;
          let node:Node = this.mEles[this.mEles.length-1];
          if(node)node.rotate(this.mRotInfo);
        }
   }

   public getWorldPos(){
          return this.node.worldPosition;
   }

   public getWorldTopPos(){
     let th2 = this.mZhuZiHei*this.unlockNum;
     let tpos = this.node.worldPosition.clone();
     tpos.y += th2;
     return tpos;
   }


   private meffPos:Vec3=new Vec3();
   private meffScale:Vec3=new Vec3(1,1,1);
   public playCompleteEff(){
     this.meffScale.y=1;
     let toff = this.mLen-4;
     if(toff>0)this.meffScale.y += toff*0.2;
     let boxOpen = this.node.getChildByName("boxOpen");
     boxOpen.setScale(this.meffScale);
     boxOpen.active=true;
     let leveUp = this.node.getChildByName("leveUp");
     this.scheduleOnce(()=>{
          boxOpen.active=false;
          leveUp.active=true;
          this.meffPos.y = this.getMaxPosY()-0.28;
          leveUp.setPosition(this.meffPos);
          leveUp.getChildByName("lightQ").getComponent(Animation).play();
     },0.6);
     this.scheduleOnce(()=>{
          leveUp.active=false;
     },1.3);
   }
   

   private isFull(){
     return this.mEles.length==this.unlockNum;
   }

   private showHui(value:boolean){
     
   }
}


